home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
util1
/
patztdir.lha
/
PATZ-TDir
/
TDirV2_10.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-15
|
12KB
|
477 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <proto/dos.h>
///» "Program-History"
/*
** Programm-History:
**
** 1.0: initial release
**
** 1.1: needs 3 runs through directories!!!
**
** 1.2: now only 1 run :)
** added possibility to sort entries (using fix arrays of pointers; needs BIIIIG stack)
**
** 2.0: changed sorting; is now performed by linked list/heap (normal stack is enough)
**
** 2.1: new switch: PATZ/S -> using Patz-Font-Output-Strings ( ¬ , ¯ ) instead of " + , ` "
** use prefs-file (ENV:TDir.prefs)
** new switch: NOPREFS/S -> do not read prefs-file
**
** 2.2: use ReadArgs() instead of selfmade parsing; multiple dirs possible now
** tests if dirs exist or not before calling ExamineDir() for the first time
** if no dirs are given, get name of currentdir and display it instead of ""
**
** 2.3: new switch: STAT/S -> print statistic (#dirs,#files) after dir-name
**
** 2.4: if file-/dir-name is too long, end it with "..." before size : file OK, dir i see no chance
** new switch: H=HELP/S prints programname and version
** new switch: N=NOTE/S prints filenote for dirs/files; NOTE: base directory gets no filenote!
**
** 2.5: if file-/dir-name is too long: place "..." in the middle of name (after 5 characters)
**
** 2.6: OutputName() procedure added
**
** 2.7: PutNode()&GetNode() procedures added
**
** 2.8: changed mode lists are ancored: now only one pointer is needed (instead of two/three)
**
** 2.9: replaced printrf() by Printf(); changed 'char tree[]' to 'char *tree[]'
** place "..." in names longer than 24 chars after 'offset' characters now (instead of fixed 5)
** changed default length of filesize from 7 to 8 (filesizes from 10 to 99 MB is reasonable i think)
** restored Printf() to printf() (is needed for OutputName anyway and saved only 2 KB)
**
** 2.10: some code-cleanup
**
*/
///«
///» "typedef"
typedef struct node {
struct node *up,*left,*right;
struct node *prev,*next;
char name[108];
char note[80];
int size; /* size<0->dir, size>=0->file */
} NODE;
///«
///» "global variables"
char *program_name="TDir 2.10";
char *program_template="DIR/M,ALL/S,DIRS/S,PLAIN/S,SP=SPACE/S,S=SORT/S,NS=NOSORT/S,PATZ/S,NP=NOPREFS/S,STAT/S,H=HELP/S,N=NOTE/S";
char *programmers_name="PATZ";
char *version_information="\0$VER: TDir 2.10 by PATZ (20.03.95)";
short break_flag=0;
int space=0,plain=0,dirs=0,all=0,sort=0,nosort=0,patz=1,stat=0,note=0;
char string[256]="";
char *tree[3]={"|","+","`"};
///«
///» "prototypes"
int Nope(void);
int PutNode(NODE **,struct FileInfoBlock *,int);
NODE * GetNode(NODE **,int);
void OutputName(NODE *,int);
void Swap(NODE *, NODE *);
void ExamineDir(char *,char *);
///«
/* procedures */
///» "Nope"
int Nope(void)
{
break_flag=5;
return(0);
}
///«
///» "PutNode"
int PutNode(NODE **base,struct FileInfoBlock *fib,int do_sorting)
{
NODE *temp=(NODE *) AllocMem(sizeof(NODE),MEMF_FAST);
if(!temp) {
printf("%s\n","Error: No memory for entry!");
break_flag=20;
return(20);
}
temp->up=temp->left=temp->right=temp->prev=temp->next=NULL;
strcpy(temp->name,fib->fib_FileName);
strcpy(temp->note,fib->fib_Comment);
if(fib->fib_DirEntryType<0) { /* file! */
temp->size=fib->fib_Size; }
else { /* dir! */
temp->size=-1;
}
/* put new entry at right place, according to switches */
if(do_sorting) { /* Heap */
if(!(*base)) { /* CreateHeap */
(*base)=temp->up=temp->next=temp->prev=temp; }
else { /* InsertHeap */
temp->up=(*base)->up; temp->prev=(*base)->prev; temp->next=(*base);
((*base)->prev)->next=temp; (*base)->prev=temp;
if(!((*base)->up)->left) {
((*base)->up)->left=temp; }
else {
((*base)->up)->right=temp; (*base)->up=((*base)->up)->next;
}
}
/* EstablishHeap */
while(temp!=(*base)&&stricmp((temp->up)->name,temp->name)>0) {
Swap(temp,temp->up); temp=temp->up;
} }
else { /* List */
if(!(*base)) { /* a[1] */
(*base)=temp->next=temp->prev=temp; }
else {
temp->next=(*base); temp->prev=(*base)->prev;
(temp->prev)->next=temp; (*base)->prev=temp;
}
}
return(0);
}
///«
///» "GetNode"
NODE * GetNode(NODE **base,int sorted)
{
NODE *temp;
if(sorted) { /* Heap */
if((*base)->next==(*base)) { /* last entry */
temp=(*base); (*base)=NULL; }
else {
Swap((*base),(*base)->prev);
temp=((*base)->prev)->up;
if(temp->right) {
temp->right=NULL; }
else {
temp->left=NULL;
}
/* Establish Heap */
temp=(*base);
while(temp->left) {
temp=temp->left;
if((temp->up)->right&&stricmp(temp->name,(temp->next)->name)>0) {
temp=temp->next;
}
if(stricmp((temp->up)->name,temp->name)<0) {
break; }
else {
Swap(temp,temp->up);
}
}
temp=(*base)->prev; (temp->prev)->next=(*base); (*base)->prev=temp->prev;
} }
else { /* Liste */
temp=(*base);
if((*base)->next==(*base)) { /* last entry */
(*base)=NULL; }
else {
(*base)=(*base)->next; (temp->prev)->next=(*base); (*base)->prev=temp->prev;
}
}
temp->up=temp->next=temp->prev=NULL;
return(temp);
}
///«
///» "OutputName"
void OutputName(NODE *t, int offset)
{
int i;
i=strlen(t->name);
if(i>24) {
Flush(Output());
printf("%.*s...%s",offset,t->name,t->name+(i-24+offset+3)); }
else {
printf("%-24s",t->name);
}
}
///«
///» "Swap"
void Swap(NODE *a, NODE *b)
{
char name[108]="";
char note[80]="";
int size;
strcpy(name,a->name); strcpy(note,a->note); size=a->size;
strcpy(a->name,b->name); strcpy(a->note,b->note); a->size=b->size;
strcpy(b->name,name); strcpy(b->note,note); b->size=size;
}
///«
///» "ExamineDir"
void ExamineDir(char *dirname,char *dirfilenote)
{
BPTR currentdir;
NODE *file=NULL;
NODE *dir=NULL;
NODE *temp=NULL;
int i;
int filecount=0,dircount=0,tmpfc=1,tmpdc=1;
BPTR MyLock;
struct FileInfoBlock *infoBlock=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_FAST);
if(!infoBlock) {
printf("%s\n","Error: Can't allocate memory for FileInfoBlock!");
break_flag=20; }
else {
MyLock=Lock(dirname,ACCESS_READ);
if(!MyLock) {
printf("Error: Can't lock \"%s\"!\n",dirname);
FreeMem(infoBlock,sizeof(struct FileInfoBlock));
break_flag=20; }
else {
if(!Examine(MyLock,infoBlock)) {
printf("%s\n","Error: Can't get infoBlock!");
FreeMem(infoBlock,sizeof(struct FileInfoBlock));
UnLock(MyLock);
break_flag=20;
}
}
}
/* read directory into arrays */
while(!break_flag&&ExNext(MyLock,infoBlock)) {
if(infoBlock->fib_DirEntryType<0) { /* file! */
filecount++;
if(!dirs) {
PutNode(&file,infoBlock,!nosort);
} }
else { /* dir! */
dircount++;
PutNode(&dir,infoBlock,sort);
}
}
/* print filenote of currently examined dir */
if(!break_flag&¬e) {
if(strcmp(dirfilenote,"")) {
printf("%s",string);
printf("%s",(all&&(filecount||dircount)&&!dirs)||(dirs&&dircount)?tree[0]:" ");
printf("%s",!stat?tree[2]:tree[1]);
printf("(%s)\n",dirfilenote);
}
}
/* print statistics */
if(!break_flag&&stat) {
if(!dircount&&!filecount) {
printf("%s %s(",string,tree[2]);
if(!plain) { printf("\x9b%s","32m"); }
printf("%s","empty");
if(!plain) { printf("\x9b%s","31m"); }
printf("%s\n",")"); }
else {
printf("%s",string);
printf("%s%s(",!dirs||(dirs&&dircount)?tree[0]:" ",tree[2]);
if(dircount) {
if(!plain) { printf("\x9b%s","32m"); }
printf("%ld dir%s",(long) dircount,dircount>1?"s":"");
if(!plain) { printf("\x9b%s","31m"); }
}
if(dircount&&filecount) {
printf("%s","/");
}
if(filecount) {
if(!plain) { printf("\x9b%s","32m"); }
printf("%ld file%s",(long) filecount,filecount>1?"s":"");
if(!plain) { printf("\x9b%s","31m"); }
}
printf("%s\n",")");
if(space&&dirs&&dircount) {
printf("%s%s\n",string,tree[0]);
}
}
}
/* process the dir-array according to switches */
while(!break_flag&&tmpdc<=dircount) {
if(space&&tmpdc!=1) {
printf("%s%s\n",string,tree[0]);
}
/* get temp from dir-array */
temp=GetNode(&dir,sort);
/* output */
printf("%s%s",string,(dircount==tmpdc&&(!filecount||dirs))?tree[2]:tree[1]);
if(!plain) { printf("\x9b%s","33m"); }
OutputName(temp,8);
printf("%s"," Dir");
if(!plain) { printf("\x9b%s","31m"); }
printf("%s\n","");
if(!break_flag&&all) {
currentdir=CurrentDir(MyLock);
i=strlen(string);
string[i]=tmpdc<dircount||(filecount&&!dirs)?*tree[0]:' '; string[i+1]=' '; string[i+2]=' '; string[i+3]=0;
ExamineDir(temp->name,temp->note);
string[i]=0;
CurrentDir(currentdir);
}
/* free temp */
FreeMem(temp,sizeof(NODE)); temp=NULL;
tmpdc++;
}
/* process the file-array according to switches */
if(!break_flag&&!dirs&&tmpfc<=filecount) {
if(space&&dircount&&filecount) {
printf("%s%s\n",string,tree[0]);
}
while(!break_flag&&tmpfc<=filecount) {
/* get temp from file-array */
temp=GetNode(&file,!nosort);
/* output */
printf("%s%s",string,filecount==tmpfc?tree[2]:tree[1]);
OutputName(temp,8);
printf(" %8ld\n",(long) temp->size);
/* print filenote of file */
if(!break_flag&¬e) {
if(strcmp(temp->note,"")) {
printf("%s",string);
printf("%s %s",tmpfc!=filecount?tree[0]:" ",tree[2]);
printf("(%s)\n",temp->note);
}
}
/* free temp */
FreeMem(temp,sizeof(NODE)); temp=NULL;
tmpfc++;
}
}
/* release memory in case of ctrl-c or other strange happenings */
if(temp) { FreeMem(temp,sizeof(NODE)); }
if(file) {
file->prev->next = NULL;
while(file) { temp=file; file=file->next; FreeMem(temp,sizeof(NODE)); }
}
if(dir) {
dir->prev->next = NULL;
while(dir) { temp=dir; dir=dir->next; FreeMem(temp,sizeof(NODE)); }
}
if(infoBlock) { FreeMem(infoBlock,sizeof(struct FileInfoBlock)); }
if(MyLock) { UnLock(MyLock); }
}
///«
///» "main"
int main(int argc, char *argv[])
{
int i;
int noprefs=0;
FILE *prefsfile;
char line[108]="";
char **try;
struct RDArgs *rdargs;
long arg[12]={NULL,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE};
BPTR MyLock;
onbreak(Nope);
/* do the argument parsing */
if(rdargs=ReadArgs(program_template,arg,NULL)) {
all =(arg[1]==DOSTRUE);
dirs =(arg[2]==DOSTRUE);
plain =(arg[3]==DOSTRUE);
space =(arg[4]==DOSTRUE);
sort =(arg[5]==DOSTRUE);
nosort =(arg[6]==DOSTRUE);
patz =(arg[7]==DOSTRUE);
noprefs=(arg[8]==DOSTRUE);
stat =(arg[9]==DOSTRUE);
/* HELP =(arg[10]==DOSTRUE); */
note =(arg[11]==DOSTRUE);
}
/* get the defaults from ENV:TDir.prefs (if file exists) */
if(!noprefs&&(prefsfile=fopen("ENV:TDir.prefs","r"))) {
i=0;while((line[i]=getc(prefsfile))!=EOF) {line[i]=toupper(line[i]); i++;}
fclose(prefsfile);
if(strstr(line,"PLAIN")) { plain=1; }
if(strstr(line,"SPACE")) { space=1; }
if(strstr(line,"DIRS")) { dirs=1; }
if(strstr(line,"ALL")) { all=1; }
if(strstr(line,"SORT")) { sort=1; }
if(strstr(line,"NOSORT")) { nosort=1; }
if(strstr(line,"PATZ")) { patz=1; }
if(strstr(line,"STAT")) { stat=1; }
if(strstr(line,"NOTE")) { note=1; }
}
if(patz) { tree[0]="|"; tree[1]="¬"; tree[2]="¯"; }
if(arg[10]==DOSTRUE) {
printf("%s by %s\n",program_name,programmers_name);
printf("%s\n","For details read the nonexisting docs :)\n"); }
else {
if(arg[0]) {
try=(char **)arg[0];
i=0;
while(!break_flag&&try[i]) {
MyLock=Lock((char *)try[i],ACCESS_READ);
if(!MyLock) {
printf("Can't find directory \"%s\"!\n\n",(char *)try[i]); i++;
}
else {
UnLock(MyLock);
printf("Directory \"%s\"\n",(char *)try[i]);
ExamineDir((char *)try[i],"");
if(!break_flag) {
printf("%s\n","");
}
i++;
}
} }
else {
MyLock=Lock("",ACCESS_READ);
if(!MyLock) {
printf("%s\n\n","Can't lock current directory!");
break_flag=20; }
else {
NameFromLock(MyLock,line,100);
UnLock(MyLock);
printf("Directory \"%s\"\n",line);
ExamineDir("","");
if(!break_flag) {
printf("%s\n","");
}
}
}
if(break_flag==5) {
printf("%s\n","***Break");
}
}
if(rdargs) { FreeArgs(rdargs); }
exit(break_flag);
}
///«